From 3d00a30898614995a3bf68af8efef538a98fe335 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 6 Jul 2004 18:02:59 +0000 Subject: [PATCH] bitkeeper revision 1.1041.5.13 (40eae953qXVB0VAXac-t2uDXq-tS9Q) Tidy up remote shutdown handling in xenolinux. --- .../arch/xen/kernel/setup.c | 86 +++++++++++++++---- 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c index b329632b78..42ef543546 100644 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c @@ -8,6 +8,8 @@ * This file handles the architecture-dependent parts of initialization */ +#define __KERNEL_SYSCALLS__ +static int errno; #include #include #include @@ -30,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1148,10 +1151,10 @@ void __init cpu_init (void) #include -/* Treat multiple suspend requests as a single one. */ -static int suspending; +/* Ignore multiple shutdown requests. */ +static int shutting_down = -1; -static void suspend_task(void *unused) +static void __do_suspend(void) { /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */ extern void blkdev_suspend(void); @@ -1220,7 +1223,7 @@ static void suspend_task(void *unused) HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT); - suspending = 0; + shutting_down = -1; memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info)); @@ -1272,25 +1275,78 @@ static void suspend_task(void *unused) free_page((unsigned long)suspend_record); } -static struct tq_struct suspend_tq; +static int shutdown_process(void *__unused) +{ + static char *envp[] = { "HOME=/", "TERM=linux", + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; + static char *restart_argv[] = { "/sbin/shutdown", "-r", "now", NULL }; + static char *poweroff_argv[] = { "/sbin/halt", "-p", NULL }; -static void shutdown_handler(ctrl_msg_t *msg, unsigned long id) + extern asmlinkage long sys_reboot(int magic1, int magic2, + unsigned int cmd, void *arg); + + daemonize(); + + switch ( shutting_down ) + { + case CMSG_SHUTDOWN_POWEROFF: + if ( execve("/sbin/halt", poweroff_argv, envp) < 0 ) + { + sys_reboot(LINUX_REBOOT_MAGIC1, + LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_POWER_OFF, + NULL); + } + break; + + case CMSG_SHUTDOWN_REBOOT: + if ( execve("/sbin/shutdown", restart_argv, envp) < 0 ) + { + sys_reboot(LINUX_REBOOT_MAGIC1, + LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_RESTART, + NULL); + } + break; + } + + return 0; +} + +static void __shutdown_handler(void *unused) { - if ( msg->subtype != CMSG_SHUTDOWN_SUSPEND ) + int err; + + if ( shutting_down != CMSG_SHUTDOWN_SUSPEND ) { - extern void ctrl_alt_del(void); - ctrl_if_send_response(msg); - ctrl_alt_del(); + err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES); + if ( err < 0 ) + printk(KERN_ALERT "Error creating shutdown process!\n"); + else + shutting_down = -1; /* could try again */ } - else if ( !suspending ) + else + { + __do_suspend(); + } +} + +static void shutdown_handler(ctrl_msg_t *msg, unsigned long id) +{ + static struct tq_struct shutdown_tq; + + if ( (shutting_down == -1) && + ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) || + (msg->subtype == CMSG_SHUTDOWN_REBOOT) || + (msg->subtype == CMSG_SHUTDOWN_SUSPEND)) ) { - suspending = 1; - suspend_tq.routine = suspend_task; - schedule_task(&suspend_tq); + shutting_down = msg->subtype; + shutdown_tq.routine = __shutdown_handler; + schedule_task(&shutdown_tq); } else { - printk(KERN_ALERT"Ignore queued suspend request\n"); + printk("Ignore spurious shutdown request\n"); } ctrl_if_send_response(msg); -- 2.30.2